package com.sduept.nwld.dataserver.controller.dataview;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.faces.context.FacesContext;
import javax.faces.view.ViewScoped;
import javax.inject.Named;

import org.apache.commons.lang.StringUtils;
import org.primefaces.event.SelectEvent;
import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.StreamedContent;
import org.springframework.beans.factory.annotation.Autowired;

import com.sduept.bigdata.fault.entity.FaultRecord;
import com.sduept.bigdata.fault.entity.FaultSourceUploadInfo;
import com.sduept.bigdata.fault.manager.DeviceFaultCountManager;
import com.sduept.bigdata.fault.manager.DeviceFaultCountManager.YearCountInfo;
import com.sduept.bigdata.fault.manager.FaultRecordQueryManager;
import com.sduept.bigdata.fault.manager.FaultSourceQueryService;
import com.sduept.bigdata.fault.model.FaultSourceCountDTO;
import com.sduept.bigdata.document.core.CommonDocumentProperties;
import com.sduept.bigdata.web.jsf.controller.AbstractController;
import com.sduept.cim.ledger.excetpion.ManagementUnitException;
import com.sduept.nwld.dataserver.manager.fault.FaultSourceQueryManager;
import com.sduept.nwld.dataserver.util.ExcelUtil;
import com.sduept.nwld.dataview.vo.fault.FaultSourceCountVO;
import com.sduept.nwld.dataview.vo.fault.FaultSourceCountVO.UnitCountInfo;
import com.sduept.nwld.fault.analysis.model.FaultUploadInfoDTO;
import com.sduept.nwld.fault.analysis.model.StationFaultUploadInfoDTO;
import com.sduept.utils.DateUtil;

@ViewScoped
@Named
public class DeviceFaultCountController extends AbstractController {
	private static final long serialVersionUID = -2172278575189297697L;
	@Autowired
	private CommonDocumentProperties pros;
	@Autowired
	private FaultSourceQueryManager fm;
	@Autowired
	private FaultRecordQueryManager frqm;
	@Autowired
	private DeviceFaultCountManager countM;
	@Autowired
	private FaultSourceQueryManager queryM;
	@Autowired
	private FaultSourceQueryService service;
	private List<FaultSourceCountDTO> countList;
	private Date startTime;
	private Date busStartTime;
	private Date transStartTime;
	private Date endTime;
	private Date busEndTime;
	private Date transEndTime;
	private String year;
	private String voltage = "500";
	private Integer vol = 500;
	private boolean showDetail = false;
	private boolean showBusDetail = false;
	private boolean showTransDetail = false;
	private StreamedContent file;
	private FaultUploadInfoDTO selected;

	private FaultUploadInfoCountDTO countDto = new FaultUploadInfoCountDTO();
	private List<FaultSourceUploadInfo> uploadInfos = new ArrayList<FaultSourceUploadInfo>();
	// 线路故障统计
	private List<FaultUploadInfoDTO> lineFaultUploadInfoDtos = new ArrayList<FaultUploadInfoDTO>();
	// 母线故障统计
	private List<FaultUploadInfoDTO> busbarFaultUploadInfoDtos = new ArrayList<FaultUploadInfoDTO>();
	// 变压器故障统计
	private List<FaultUploadInfoDTO> transFaultUploadInfoDtos = new ArrayList<FaultUploadInfoDTO>();

	// 故障按月份统计表格展示所用数据
	private String year1;
	private String month1;
	private String unitType1 = "0"; // 0:调度单位；1：运维单位
	private List<FaultSourceCountVO> items;
	private Boolean showTable = true;
	List<UnitCountInfo> unitCountInfos = new ArrayList<>();

	// 故障按年统计
	private String deptCountYear;
	private String countTypeDept = "0"; // 0:调度单位；1：运维单位
	private List<YearCountInfo> yearCountInfos = new ArrayList<YearCountInfo>();
	private List<String> yearCountDetail = new ArrayList<String>();
	private List<Integer> months = new ArrayList<>();
	private Boolean showYearCountTable = true;
	private String startMonth; // 年统计--初始月份
	private String endMonth;// 年统计 --结束月份

	@PostConstruct
	public void init() {
		initMonth();
		Date current = new Date();
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(current);
		calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), 
			23, 59, 59);//设置当天23:59:59
		current = calendar.getTime();
//		calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - 1);
		calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) - 1, calendar.get(Calendar.DAY_OF_MONTH), 
			00, 00, 00);//设置上月当天凌晨00:00:00
		initTimes(calendar, current);
		// 线路故障页面展示DTO
		lineFaultUploadInfoDtos = fm.getFaultUploadInfoDTOByEtypeVoltageDate(vol, "线路", calendar.getTime(), current);
		initCountTableData();
		lineFaultUploadInfoDtos=initIntactRate(lineFaultUploadInfoDtos);
	}
   /**
    * 计算完好率
    * @param lineFaultUploadInfoDtos2
 * @return 
    */
	private List<FaultUploadInfoDTO> initIntactRate(List<FaultUploadInfoDTO> lineFaultUploadInfoDtos) {
		// TODO Auto-generated method stub
		for (FaultUploadInfoDTO fd : lineFaultUploadInfoDtos) {
			fd.setCentralWave(getIntactRate(fd, 0));;
			fd.setProtectEventIntactRate(getIntactRate(fd, 1));
			fd.setProtectWaveIntactRate(getIntactRate(fd, 2));;
			fd.setTotalIntactRate(getIntactRate(fd, 3));
		}
		return lineFaultUploadInfoDtos;
	}

	/**
	 * 加载/重置月份（12个月）
	 * 如果有初始月份和结束月份有数值，只加载>初始月份，< 结束月份的月
	 * 如果初始月份和结束月份不完整，则加载全部月份（1-12月）
	 */
	private void initMonth() {
		months.clear();
		if (StringUtils.isNotEmpty(startMonth) && StringUtils.isNotEmpty(endMonth) && Integer.parseInt(startMonth) != 0
				&& Integer.parseInt(endMonth) != 0) {
			for (int i = Integer.parseInt(startMonth); i <= Integer.parseInt(endMonth); i++) {
				months.add(i);
			}
		} else {
			for (int i = 1; i <= 12; i++) {
				months.add(i);
			}
			startMonth = "1";
			endMonth = "12";
		}
	}

	private void initTimes(Calendar calendar, Date current) {
		startTime = calendar.getTime();
		endTime = current;
		busStartTime = calendar.getTime();
		busEndTime = current;
		transStartTime = calendar.getTime();
		transEndTime = current;
	}

	/**
	 * 重新统计当前选中的故障的故障源
	 */
	public void reloadSingleFaultSource() {
		FaultRecord record = frqm.findById(selected.getRecordId());
		lineFaultUploadInfoDtos = fm.getFaultUploadInfoDTOByFaultRecord(record);
		selected = null;
		lineFaultUploadInfoDtos=initIntactRate(lineFaultUploadInfoDtos);
	}

	/**
	 * 加载故障统计数据
	 */
	public void initFaultCountData() {
		Date current = new Date();
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(current);
		countList = countM.getFaultSourceCountDTOByYear(String.valueOf(calendar.get(Calendar.YEAR)));
	}

	/**
	 * 加载母线保护数据
	 */
	public void initBusData() {
		busbarFaultUploadInfoDtos = fm.getFaultUploadInfoDTOByDate("母线", busStartTime, busEndTime);
		busbarFaultUploadInfoDtos=initIntactRate(busbarFaultUploadInfoDtos);
	}

	/**
	 * 加载变压器数据
	 */
	public void initTransformerData() {
		transFaultUploadInfoDtos = fm.getFaultUploadInfoDTOByDate("变压器", transStartTime, transEndTime);
		transFaultUploadInfoDtos=initIntactRate(transFaultUploadInfoDtos);
	}

	public void showDetail() {
		showDetail = !showDetail;
	}

	public void showBusDetail() {
		showBusDetail = !showBusDetail;
	}

	public void showTransDetaill() {
		showTransDetail = !showTransDetail;
	}

	private void formatQueryCondition() {
		endTime = new Date(endTime.getTime() + 86399000);// 相当于到23:59:59
		vol = null;
		if (!StringUtils.isEmpty(voltage)) {
			vol = new Integer(voltage);
		}
	}

	public void queryAction() {
		formatQueryCondition();
		if (null == vol) {
			lineFaultUploadInfoDtos = fm.getFaultUploadInfoDTOByDate("线路", startTime, endTime);
		} else {
			lineFaultUploadInfoDtos = fm.getFaultUploadInfoDTOByEtypeVoltageDate(vol, "线路", startTime, endTime);
		}
		lineFaultUploadInfoDtos = initIntactRate(lineFaultUploadInfoDtos);
	}

	public void queryCountSummary() {
		countList = countM.getFaultSourceCountDTOByYear(year);
	}

	public String getStateStr(String str) {
		if (StringUtils.isEmpty(str)) {
			return "";
		} else if (str.equals("-1")) {
			return "X";
		} else {
			return "√";
		}
	}

	public String getCentralizedStr(String str) {
		if (StringUtils.isEmpty(str)) {
			return "";
		} else if (str.equals("-1")) {
			return "X";
		} else {
			return "√";
		}
	}

	public String getNamePlaceStr(String str) {
		if (StringUtils.isEmpty(str)) {
			return "";
		} else {
			return str;
		}
	}

	public String getRate(String completeCount, String inCompleteCount) {
		if (completeCount.equals("0")) {
			return "0%";
		} else if (inCompleteCount.equals("0")) {
			return "100%";
		}
		Float c1 = Float.valueOf(completeCount);
		Float c2 = Float.valueOf(inCompleteCount);
		return String.format("%.2f", c1 / (c2 + c1) * 100) + "%";
	}

	public void changeYear() {
		FacesContext context = FacesContext.getCurrentInstance();
		Map<String, String> map = context.getExternalContext().getRequestParameterMap();
		year = map.get("year").toString();
		queryCountSummary();
	}

	private void preDownLoad() {
		formatQueryCondition();
		// 查询各部分的数据
		lineFaultUploadInfoDtos = fm.getFaultUploadInfoDTOByEtypeVoltageDate(vol, "线路", startTime, endTime);
		busbarFaultUploadInfoDtos = fm.getFaultUploadInfoDTOByDate("母线", startTime, endTime);
		transFaultUploadInfoDtos = fm.getFaultUploadInfoDTOByDate("变压器", startTime, endTime);
		initIntactRate(lineFaultUploadInfoDtos);
		initIntactRate(busbarFaultUploadInfoDtos);
		initIntactRate(transFaultUploadInfoDtos);
//		String startStr = DateUtil.getStringDate(startTime, DateUtil.pattern_ymdhm);
//		countList = countM.getFaultSourceCountDTOByYear(startStr.substring(0, 4));
	}

	public void fileDownLoad() {
		preDownLoad();
		FileOutputStream os = null;
		FileInputStream is = null;
		try {
			os = new FileOutputStream(new File(pros.getExportTempPath() + "fault.xls"));
//			ExcelUtil.writeFaultReportCache(lineFaultUploadInfoDtos,busbarFaultUploadInfoDtos,transFaultUploadInfoDtos,countList, os);
			ExcelUtil.writeFaultReportCache(lineFaultUploadInfoDtos, busbarFaultUploadInfoDtos,
					transFaultUploadInfoDtos, os);
			is = new FileInputStream(new File(pros.getExportTempPath() + "fault.xls"));
			String start = DateUtil.getStringDate(startTime, DateUtil.pattern_ymd);
			String end = DateUtil.getStringDate(endTime, DateUtil.pattern_ymd);

			file = new DefaultStreamedContent(is, "xls", start + "__" + end + ".xls");
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} finally {
			try {
				os.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public void yearFileDownLoad() {
		FileOutputStream os = null;
		FileInputStream is = null;
		try {
			os = new FileOutputStream(new File(pros.getExportTempPath() + "faultCountByYear.xls"));
			ExcelUtil.exportFaultSourceCountByYear(yearCountInfos, os);
			is = new FileInputStream(new File(pros.getExportTempPath() + "faultCountByYear.xls"));
			file = new DefaultStreamedContent(is, "xls", deptCountYear + ".xls");
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} finally {
			try {
				os.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public void monthFileDownLoad() {
		FileOutputStream os = null;
		FileInputStream is = null;
		try {
			os = new FileOutputStream(new File(pros.getExportTempPath() + "faultCountByMonth.xls"));
			ExcelUtil.exportFaultSourceCountByMonth(items, os);
			is = new FileInputStream(new File(pros.getExportTempPath() + "faultCountByMonth.xls"));
			file = new DefaultStreamedContent(is, "xls", year1 + "_" + month1 + ".xls");
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} finally {
			try {
				os.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 点击统计按钮时，从数据库中读取记录
	 */
	public void getLineFaultUploadInfos() {
		formatQueryCondition();
		uploadInfos = fm.getFaultUploadInfoByEtypeVoltageDate(vol, "线路", startTime, endTime);
		// 封装表格展示数据
		calculateFaultUploadDetail();
		
		
	}

	/**
	 * 统计集中录波、保护录波、保护事件的上送次数，用于表格展示 
	 */
	private void calculateFaultUploadDetail() {
		countDto = new FaultUploadInfoCountDTO();
		for (FaultSourceUploadInfo info : uploadInfos) {
			if (countM.isCenterWave(info)) {
				setCenterWaveDetail(info); // 集中录波
			} else if (countM.isProtectWave(info)) {
				setProtectWaveDetail(info); // 保护录波(主保护和断路器保护录波)
			} else if (countM.isProtectEvent(info)) {
				setProtectEventDetail(info); // 保护事件(主保护和断路器保护事件)
			}
		}
	}

	/**
	 * 设置集中录波评价次数
	 * @param info
	 */
	private void setCenterWaveDetail(FaultSourceUploadInfo info) {
		countDto.setCenterWaveShould(countDto.getCenterWaveShould() + 1); // 应评价次数
		if (0 == info.getUploadMethod()) {
			countDto.setCenterWaveActualUpload(countDto.getCenterWaveActualUpload() + 1); // 自动上送次数
		}
		if (1 == info.getUploadMethod()) {
			countDto.setCenterWaveManualUpload(countDto.getCenterWaveManualUpload() + 1); // 手动上送次数
		}

	}

	/**
	 * 设置主保护录波评价次数
	 * @param info
	 */
	private void setProtectWaveDetail(FaultSourceUploadInfo info) {
		countDto.setProtectWaveShould(countDto.getProtectWaveShould() + 1); // 应评价次数
		if (0 == info.getUploadMethod()) {
			countDto.setProtectWaveActualUpload(countDto.getProtectWaveActualUpload() + 1); // 自动上送次数
		}
		if (1 == info.getUploadMethod()) {
			countDto.setProtectWaveManualUpload(countDto.getProtectWaveManualUpload() + 1); // 手动上送次数
		}
	}

	/**
	 * 设置保护事件评价次数
	 * @param info
	 */
	private void setProtectEventDetail(FaultSourceUploadInfo info) {
		countDto.setProtectEventShould(countDto.getProtectEventShould() + 1); // 保护事件应评价次数
		if (0 == info.getUploadMethod()) {
			countDto.setProtectEventActualUpload(countDto.getProtectEventActualUpload() + 1); // 保护事件自动上送次数
		}
		if (1 == info.getUploadMethod()) {
			countDto.setProtectEventManualUpload(countDto.getProtectEventManualUpload() + 1); // 保护事件手动上送次数
		}
	}

	public void query() {
		items = genFaultSourceCountVO(year1, month1, unitType1);
	}
	

	/**
	 * 根据年份/月份/分组类型 生成故障源统计分析模型
	 * @param year
	 * @param month
	 * @param unitType
	 * @return
	 */
	private List<FaultSourceCountVO> genFaultSourceCountVO(String year, String month, String unitType) {
		List<FaultSourceCountVO> list = new ArrayList<FaultSourceCountVO>();
		if (null != year && null != month) {
			List<FaultSourceUploadInfo> infos = queryM.findFaultSourceUploadInfo(Integer.parseInt(year),
					Integer.parseInt(month));
			Map<String, Map<String, List<FaultSourceUploadInfo>>> map;
			try {
				map = countM.groupListByUnitType(infos, unitType);
				for (String dataSource : map.keySet()) {
					FaultSourceCountVO vo = new FaultSourceCountVO();
					vo.setType(dataSource);
					list.add(setFaultSourceCountVO(vo, map.get(dataSource),dataSource));
					getUnitCountInfo(list);
				}
			} catch (ManagementUnitException e) {
				e.printStackTrace();
			}
		}
		return list;
	}
	
    private void getUnitCountInfo(List<FaultSourceCountVO> list){
    	unitCountInfos.clear();
    	 Map<String,List<UnitCountInfo>> unitMap = new HashMap<String, List<UnitCountInfo>>();
    	for(FaultSourceCountVO vo: list) {
    		 List<UnitCountInfo> units = vo.getUnits();
    		 for(UnitCountInfo info:units) {
    	    		if(unitMap.containsKey(info.getName())) {
    	    			List<UnitCountInfo>	infos = unitMap.get(info.getName());
    	    			infos.add(info);
    	    		}else {
    	    			List<UnitCountInfo> infos = new ArrayList<>();
    	    			infos.add(info);
    	    			unitMap.put(info.getName(), infos);
    	    		}
    		 }
    	}
    	for(String key:unitMap.keySet()) {
    		List<UnitCountInfo> infos = unitMap.get(key);
    		unitCountInfos.addAll(infos);
    	}
    }
	
	
	private FaultSourceCountVO setFaultSourceCountVO(FaultSourceCountVO vo,
			Map<String, List<FaultSourceUploadInfo>> deptMap,String dataSource) {
		List<UnitCountInfo> us = new ArrayList<>();
		for (String dept : deptMap.keySet()) {
			UnitCountInfo infoVO = vo.new UnitCountInfo();
			infoVO.setName(dept);
			List<FaultSourceUploadInfo> list = deptMap.get(dept);
			for (FaultSourceUploadInfo info : list) {
				infoVO.setTargetTotal(infoVO.getTargetTotal() + 1);
				if (0 == info.getUploadMethod()) { // 自动上送
					infoVO.setAutomatic(infoVO.getAutomatic() + 1);
				} else if (1 == info.getUploadMethod()) { // 人工上送
					infoVO.setManual(infoVO.getManual() + 1);
				}
			}
			infoVO.setUpTotal(infoVO.getManual(), infoVO.getAutomatic());
			infoVO.setUploadRatio(infoVO.getUpTotal(), infoVO.getTargetTotal());
			infoVO.setWaveType(dataSource);
			us.add(infoVO);
		}
		vo.setUnits(sortByUploadRatio(us));
		UnitCountInfo total = getTotal(vo);
		vo.setTotal(total);
		return vo;
	}

	private UnitCountInfo getTotal(FaultSourceCountVO vo) {
		UnitCountInfo totalInfoVO = vo.new UnitCountInfo();
		List<UnitCountInfo> list = vo.getUnits();
		for (UnitCountInfo infoVO : list) {
			totalInfoVO.setAutomatic(totalInfoVO.getAutomatic() + infoVO.getAutomatic());
			totalInfoVO.setManual(totalInfoVO.getManual() + infoVO.getManual());
			totalInfoVO.setTargetTotal(totalInfoVO.getTargetTotal() + infoVO.getTargetTotal());
		}
		totalInfoVO.setUpTotal(totalInfoVO.getManual(), totalInfoVO.getAutomatic());
		totalInfoVO.setUploadRatio(totalInfoVO.getUpTotal(), totalInfoVO.getTargetTotal());
		return totalInfoVO;
	}

	private List<UnitCountInfo> sortByUploadRatio(List<UnitCountInfo> list) {
		Collections.sort(list, new Comparator<UnitCountInfo>() {
			public int compare(UnitCountInfo o1, UnitCountInfo o2) {
				if (o1.getUploadRatio() > o2.getUploadRatio()) {
					return -1;
				} else if (o1.getUploadRatio() < o2.getUploadRatio()) {
					return 1;
				} else {
					return 0;
				}
			}
		});
		return list;
	}

	/**
	 * 录波信息上送情况统计结果
	 */
	public class FaultUploadInfoCountDTO {
		/**
		 * 集中录波应评价次数
		 */
		private int centerWaveShould;
		/**
		 * 集中录波自动上送次数
		 */
		private int centerWaveActualUpload;
		/**
		 * 集中录波人工上送次数
		 */
		private int centerWaveManualUpload;

		/**
		 * 保护录波应评价次数
		 */
		private int protectWaveShould;
		/**
		 * 保护录波自动上送次数
		 */
		private int protectWaveActualUpload;
		/**
		 * 保护录波人工上送次数
		 */
		private int protectWaveManualUpload;

		/**
		 * 保护事件应评价次数
		 */
		private int protectEventShould;
		/**
		 * 保护事件自动评价次数
		 */
		private int protectEventActualUpload;
		/**
		 * 保护事件人工评价次数
		 */
		private int protectEventManualUpload;

		public int getCenterWaveShould() {
			return centerWaveShould;
		}

		public void setCenterWaveShould(int centerWaveShould) {
			this.centerWaveShould = centerWaveShould;
		}

		public int getCenterWaveActualUpload() {
			return centerWaveActualUpload;
		}

		public void setCenterWaveActualUpload(int centerWaveActualUpload) {
			this.centerWaveActualUpload = centerWaveActualUpload;
		}

		public int getCenterWaveManualUpload() {
			return centerWaveManualUpload;
		}

		public void setCenterWaveManualUpload(int centerWaveManualUpload) {
			this.centerWaveManualUpload = centerWaveManualUpload;
		}

		public int getProtectWaveShould() {
			return protectWaveShould;
		}

		public void setProtectWaveShould(int protectWaveShould) {
			this.protectWaveShould = protectWaveShould;
		}

		public int getProtectWaveActualUpload() {
			return protectWaveActualUpload;
		}

		public void setProtectWaveActualUpload(int protectWaveActualUpload) {
			this.protectWaveActualUpload = protectWaveActualUpload;
		}

		public int getProtectWaveManualUpload() {
			return protectWaveManualUpload;
		}

		public void setProtectWaveManualUpload(int protectWaveManualUpload) {
			this.protectWaveManualUpload = protectWaveManualUpload;
		}

		public int getProtectEventShould() {
			return protectEventShould;
		}

		public void setProtectEventShould(int protectEventShould) {
			this.protectEventShould = protectEventShould;
		}

		public int getProtectEventActualUpload() {
			return protectEventActualUpload;
		}

		public void setProtectEventActualUpload(int protectEventActualUpload) {
			this.protectEventActualUpload = protectEventActualUpload;
		}

		public int getProtectEventManualUpload() {
			return protectEventManualUpload;
		}

		public void setProtectEventManualUpload(int protectEventManualUpload) {
			this.protectEventManualUpload = protectEventManualUpload;
		}
	}
    
	private void initCountTableData() {
		Calendar cal = Calendar.getInstance();
		Integer y = cal.get(Calendar.YEAR);
		year1 = y.toString();
		Integer m = cal.get(Calendar.MONTH) + 1;
		month1 = m.toString();
		// 故障年统计查询year
		deptCountYear = y.toString();
	}

	/**
	 * 根据年份统计故障源信息
	 */
	public void queryCountTypeByYear() {
		initMonth();
		yearCountInfos = countM.getYearCountInfos(deptCountYear, countTypeDept);
	}

	/**
	 * 根据年份和月份区间统计故障源信息
	 */
	public void queryCountInfoByYearAndMonths() {
		if (Integer.parseInt(startMonth) == 0 || Integer.parseInt(endMonth) == 0) {
			queryCountTypeByYear();
		} else if (Integer.parseInt(startMonth) != 0 && Integer.parseInt(endMonth) != 0) {
			initMonth();
			try {
				yearCountInfos = countM.getCountInfoByYearAndMonths(deptCountYear, countTypeDept, startMonth, endMonth);
			} catch (ManagementUnitException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 获得完好率  0:集中录波完好率  1：保护事件完好率  2：保护录波完好率  3：综合上报完好率
	 * @return
	 */
	public int getIntactRate(FaultUploadInfoDTO info,int type) {//TODO
		List<StationFaultUploadInfoDTO> sfd = info.getStationInfo();
		return intactRate(sfd,type);
	}
	/**
	 * 各类完好率统计
	 * @param sfd
	 * @param type 
	 * @return
	 */
	private int intactRate(List<StationFaultUploadInfoDTO> sfd, int type) {
		double rate = 0 ,total = 0,success = 0;
		for (StationFaultUploadInfoDTO sf : sfd) {
			List<Double> result = new ArrayList<>();
			if(type==0) {//集中录波完好率
				result = getTotalAndSuccessNumberForCentralWave(sf,total,success,result);
			}else if(type==1) {//保护事件完好率
				result = getTotalAndSuccessNumberForProtectEvent(sf,total,success,result);
			}else if(type==2) {//保护录波完好率
				result =  getTotalAndSuccessNumberForProtectWave(sf,total,success,result);
			}else if(type==3) {//综合上报完好率
				result = getTotalAndSuccessNumberForWhole(sf,total,success,result);
			}
			total = result.get(0);
			success = result.get(1);
		}
		if(success==0||total==0) {
			return 0;
		}else {
			rate = numberUtil(success/total);
		}
		int result = (int) (rate*100);
		return result;
	}
	/**
	 * 综合统计数量
	 * @param sf
	 * @param total
	 * @param success
	 * @param result 
	 * @param result
	 * @return
	 */
	private List<Double> getTotalAndSuccessNumberForWhole(StationFaultUploadInfoDTO sf, double total, double success, List<Double> result) {
		double sum=0,successCount = 0,firstNum=0,secondNum=0;
		firstNum=getTotalAndSuccessNumberForCentralWave(sf,total,success,new ArrayList<Double>()).get(0);
		secondNum=getTotalAndSuccessNumberForProtectEvent(sf,firstNum,success,new ArrayList<Double>()).get(0);
		sum=getTotalAndSuccessNumberForProtectWave(sf,secondNum,success,new ArrayList<Double>()).get(0);
		firstNum=0;secondNum=0;
		firstNum=getTotalAndSuccessNumberForCentralWave(sf,total,success,new ArrayList<Double>()).get(1);
		secondNum=getTotalAndSuccessNumberForProtectEvent(sf,total,firstNum,new ArrayList<Double>()).get(1);
		successCount=getTotalAndSuccessNumberForProtectWave(sf,total,secondNum,new ArrayList<Double>()).get(1);
		result.add(sum);
		result.add(successCount);
		return result;
	}

	/**
	 * 获得保护录波总数量和上送数量统计
	 * @param sf
	 * @param total
	 * @param success
	 * @param result
	 * @return
	 */
   private List<Double> getTotalAndSuccessNumberForProtectWave(StationFaultUploadInfoDTO sf, double total,
			double success, List<Double> result) {
	   if(sf.getMain1WaveInfo()!=null) {//主一录波 
			total++;
			if(sf.getMain1WaveInfo()!=-1) {
				success++;
		    }
		}
		if(sf.getMain2WaveInfo()!=null) {
			total++;
			if(sf.getMain2WaveInfo()!=-1) {
				success++;
		    }
		}
		if(sf.getMain3WaveInfo()!=null) {
			total++;
			if(sf.getMain3WaveInfo()!=-1) {
				success++;
		    }
		}
		if(sf.getBreakerProtect1WaveInfo()!=null) {
			total++;
			if(sf.getBreakerProtect1WaveInfo()!=-1) {
				success++;
		    }
		}
	    if(sf.getBreakerProtect2WaveInfo()!=null) {
	    	total++;
			if(sf.getBreakerProtect2WaveInfo()!=-1) {
				success++;
		    }
	    }
	    result.add(total);
	    result.add(success);
		return result;
	}

    /**
     * 获得保护事件总数量和上送数量统计
     * @param sf
     * @param total
     * @param success
     * @param result
     * @return
     */
	private List<Double> getTotalAndSuccessNumberForProtectEvent(StationFaultUploadInfoDTO sf, double total, double success, List<Double> result) {
		if(sf.getMain1DatagramInfo()!=null) {//主一报文 即 主一保护动作
			total++;
			if(sf.getMain1DatagramInfo()!=-1) {
				success++;
		    }
		}
		if(sf.getMain2DatagramInfo()!=null) {
			total++;
			if(sf.getMain2DatagramInfo()!=-1) {
				success++;
		    }
		}
		if(sf.getMain3DatagramInfo()!=null) {
			total++;
			if(sf.getMain3DatagramInfo()!=-1) {
				success++;
		    }
		}
		if(sf.getBreakerProtect1DatagramInfo()!=null) {
			total++;
			if(sf.getBreakerProtect1DatagramInfo()!=-1) {
				success++;
		    }
		}
	    if(sf.getBreakerProtect2DatagramInfo()!=null) {
	    	total++;
			if(sf.getBreakerProtect2DatagramInfo()!=-1) {
				success++;
		    }
	    }
	    result.add(total);
	    result.add(success);
		return result;
	}

	/**
	 * 获得集中录波总数量和上送数量统计
	 * @param success 
	 * @param total 
	 * @param sf 
	 * @param result 
	 * @return
	 */
	private List<Double> getTotalAndSuccessNumberForCentralWave(StationFaultUploadInfoDTO sf, double total, double success, List<Double> result) {
			if(sf.getWaveInfo()!=null) {
				total++;
				if(sf.getWaveInfo()!=-1) {//完成
					success++;
				}
			}
			result.add(total);
			result.add(success);
		    return result;
	}

	private double numberUtil(double rate) {
		 BigDecimal b = new BigDecimal(rate);  
		 rate = b.setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();  
		return rate;
	}
	
	/**
	 * 获取详细信息
	 */
	public List<String> getCountDetail(Integer month, YearCountInfo info) {
		List<String> lt = info.getUploadRatio().get(month);
		return lt;
	}

	public void getYearCountDetail1(Integer month, YearCountInfo info) {
		yearCountDetail = info.getUploadRatio().get(month);
	}

	public void showChart() {
		showTable = false;
	}

	public void showTable() {
		showTable = true;
		query();
	}

	public void changeTableYear() {
		FacesContext context = FacesContext.getCurrentInstance();
		Map<String, String> map = context.getExternalContext().getRequestParameterMap();
		year1 = map.get("year").toString();
	}

	public void showYearCountChart() {
		showYearCountTable = false;
	}

	public void showYearCountTable() {
		showYearCountTable = true;
		queryCountInfoByYearAndMonths();
	}

	/**
	 * 故障信息上送率年统计--年份修改
	 */
	public void changeDeptCountYear() {
		FacesContext context = FacesContext.getCurrentInstance();
		Map<String, String> map = context.getExternalContext().getRequestParameterMap();
		deptCountYear = map.get("year").toString();
	}

	public void onRowSelect(SelectEvent event) {
		selected = (FaultUploadInfoDTO) event.getObject();
	}

	public void onBusRowSelect(SelectEvent event) {

	}

	public String formatterDate(String dateStr) {
		return dateStr.substring(0, dateStr.length() - 2);
	}

	public Date getStartTime() {
		return startTime;
	}

	public void setStartTime(Date startTime) {
		this.startTime = startTime;
	}

	public Date getEndTime() {
		return endTime;
	}

	public void setEndTime(Date endTime) {
		this.endTime = endTime;
	}

	public boolean isShowDetail() {
		return showDetail;
	}

	public void setShowDetail(boolean showDetail) {
		this.showDetail = showDetail;
	}

	public List<FaultSourceCountDTO> getCountList() {
		return countList;
	}

	public void setCountList(List<FaultSourceCountDTO> countList) {
		this.countList = countList;
	}

	public String getYear() {
		return year;
	}

	public void setYear(String year) {
		this.year = year;
	}

	public Date getBusStartTime() {
		return busStartTime;
	}

	public void setBusStartTime(Date busStartTime) {
		this.busStartTime = busStartTime;
	}

	public Date getTransStartTime() {
		return transStartTime;
	}

	public void setTransStartTime(Date transStartTime) {
		this.transStartTime = transStartTime;
	}

	public Date getBusEndTime() {
		return busEndTime;
	}

	public void setBusEndTime(Date busEndTime) {
		this.busEndTime = busEndTime;
	}

	public Date getTransEndTime() {
		return transEndTime;
	}

	public void setTransEndTime(Date transEndTime) {
		this.transEndTime = transEndTime;
	}

	public boolean isShowBusDetail() {
		return showBusDetail;
	}

	public void setShowBusDetail(boolean showBusDetail) {
		this.showBusDetail = showBusDetail;
	}

	public boolean isShowTransDetail() {
		return showTransDetail;
	}

	public void setShowTransDetail(boolean showTransDetail) {
		this.showTransDetail = showTransDetail;
	}

	public String getVoltage() {
		return voltage;
	}

	public void setVoltage(String voltage) {
		this.voltage = voltage;
	}

	public StreamedContent getFile() {
		return file;
	}

	public void setFile(StreamedContent file) {
		this.file = file;
	}

	public FaultUploadInfoCountDTO getCountDto() {
		return countDto;
	}

	public void setCountDto(FaultUploadInfoCountDTO countDto) {
		this.countDto = countDto;
	}

	public List<FaultUploadInfoDTO> getLineFaultUploadInfoDtos() {
		return lineFaultUploadInfoDtos;
	}

	public void setLineFaultUploadInfoDtos(List<FaultUploadInfoDTO> lineFaultUploadInfoDtos) {
		this.lineFaultUploadInfoDtos = lineFaultUploadInfoDtos;
	}

	public FaultUploadInfoDTO getSelected() {
		return selected;
	}

	public void setSelected(FaultUploadInfoDTO selected) {
		this.selected = selected;
	}

	public List<FaultUploadInfoDTO> getBusbarFaultUploadInfoDtos() {
		return busbarFaultUploadInfoDtos;
	}

	public void setBusbarFaultUploadInfoDtos(List<FaultUploadInfoDTO> busbarFaultUploadInfoDtos) {
		this.busbarFaultUploadInfoDtos = busbarFaultUploadInfoDtos;
	}

	public List<FaultUploadInfoDTO> getTransFaultUploadInfoDtos() {
		return transFaultUploadInfoDtos;
	}

	public void setTransFaultUploadInfoDtos(List<FaultUploadInfoDTO> transFaultUploadInfoDtos) {
		this.transFaultUploadInfoDtos = transFaultUploadInfoDtos;
	}

	public List<FaultSourceCountVO> getItems() {
		return items;
	}

	public void setItems(List<FaultSourceCountVO> items) {
		this.items = items;
	}

	public Integer getVol() {
		return vol;
	}

	public void setVol(Integer vol) {
		this.vol = vol;
	}

	public List<FaultSourceUploadInfo> getUploadInfos() {
		return uploadInfos;
	}

	public void setUploadInfos(List<FaultSourceUploadInfo> uploadInfos) {
		this.uploadInfos = uploadInfos;
	}

	public String getYear1() {
		return year1;
	}

	public void setYear1(String year1) {
		this.year1 = year1;
	}

	public String getMonth1() {
		return month1;
	}

	public void setMonth1(String month1) {
		this.month1 = month1;
	}

	public String getUnitType1() {
		return unitType1;
	}

	public void setUnitType1(String unitType1) {
		this.unitType1 = unitType1;
	}

	public Boolean getShowTable() {
		return showTable;
	}

	public void setShowTable(Boolean showTable) {
		this.showTable = showTable;
	}

	public String getCountTypeDept() {
		return countTypeDept;
	}

	public void setCountTypeDept(String countTypeDept) {
		this.countTypeDept = countTypeDept;
	}

	public List<YearCountInfo> getYearCountInfos() {
		return yearCountInfos;
	}

	public void setYearCountInfos(List<YearCountInfo> yearCountInfos) {
		this.yearCountInfos = yearCountInfos;
	}

	public List<String> getYearCountDetail() {
		return yearCountDetail;
	}

	public void setYearCountDetail(List<String> yearCountDetail) {
		this.yearCountDetail = yearCountDetail;
	}

	public List<Integer> getMonths() {
		return months;
	}

	public void setMonths(List<Integer> months) {
		this.months = months;
	}

	public String getDeptCountYear() {
		return deptCountYear;
	}

	public void setDeptCountYear(String deptCountYear) {
		this.deptCountYear = deptCountYear;
	}

	public Boolean getShowYearCountTable() {
		return showYearCountTable;
	}

	public void setShowYearCountTable(Boolean showYearCountTable) {
		this.showYearCountTable = showYearCountTable;
	}

	public String getStartMonth() {
		return startMonth;
	}

	public void setStartMonth(String startMonth) {
		this.startMonth = startMonth;
	}

	public String getEndMonth() {
		return endMonth;
	}

	public void setEndMonth(String endMonth) {
		this.endMonth = endMonth;
	}

	public List<UnitCountInfo> getUnitCountInfos() {
		return unitCountInfos;
	}

	public void setUnitCountInfos(List<UnitCountInfo> unitCountInfos) {
		this.unitCountInfos = unitCountInfos;
	}

}
